# PacMan (Galaxian hardware) - Disassembly

This repository contains a dz80 control file to disassemble and comment the PacMan code that runs in Galaxian hardware.

This is work in progress.

## How to Use

- Install `d52`. Debian: `sudo apt-get install d52`; other systems: no idea, but the package is here: http://www.efton.sk/t0t1/d52v341.zip
- Grab _puckman.zip_ from a MAME distribution with merged ROMs. Unzip it to a temporary directory.
- With bash, use: `cat pacmanbl/{1..7} > pacmanbl.bin`
- Move _pacmanbl.bin_ to the directory where _pacmanbl.ctl_ is. You can now remove the temporary directory.
- From the directory containing _pacmanbl.bin_ and _pacmanbl.ctl_, run: `dz80 pacmanbl.bin` (for just the listing) or `dz80 -d pacmanbl.bin` (for embedding address and data info in the listing).

The last step will generate a `pacmanbl.z80` file with the assembly listing.

## Highlights

The code uses a command queue. There are 32 command codes, from 00h to 1Fh. Each command has a parameter. `RST 28h` is used to enqueue a command; the two bytes following the `RST 28h` instruction are the command and the parameter. The comments at addresses 2314h-2352h explain the commands. The command handling routines are called with the parameter in register B.

When the on-reset initialization finishes, the main loop is executed. This loop is limited to checking the queue for commands and executing them if there are any. The rest of the logic is in the NMI interrupt routine.

Maskable interrupts are always disabled. The interrupt routine at 38h enters an endless loop that only disables NMI and refreshes the watchdog, effectively forcing a freeze. Possibly used for debugging.

Restart routines:

- `RST 00h`: Reset.
- `RST 08h`: Fills B bytes with A, starting in HL. Returns with A unchanged, B = 0 and HL pointing to the first byte that wasn't filled.
- `RST 10h`: Byte array access, using A as index; HL points to the array. Returns A = value, HL pointing to the byte.
- `RST 18h`: Word array access, using B as index; HL points to the array. Returns HL = value; destroys DE and A.
- `RST 20h`: Jump table. Given an address array right after the `RST 20h` opcode, use A as index into the element and jump to it. Note that it's a jump, not a call.
- `RST 28h`: Enqueue a command and parameter. Both immediately follow the `RST 28h` opcode.
- `RST 30h`: Purpose still unknown. Looks for a spot in a strided list of 16 records of 3 bytes each, starting at 4090h, at which the first byte of the triplet is zero; if one is found, the 3 bytes following the `RST 30h` opcode are read and stored in that spot. If not found, it returns without skipping the 3 bytes, potentially causing a crash, so it's suspected that the programmers knew that there would always be a free spot.
- `RST 38h`: Purpose unknown; suspected use in debugging or diagnostics. Continuously disables NMI and refreshes the watchdog, causing a freeze.
